// Copyright 2007 Helsinki Institute for Information Technology
// and the authors.
//
// Authors: Harri Hämäläinen <harri.hamalainen@helsinki.fi>

// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation files
// (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

// TODO:    -Removing enclosures from entry should remove enclosure from DB?

// Connector
function FeedConnector(coll_id) {
    var collection = coll_id;
    var entries = null;
    var comments = null;
    var tags = null;
    var info = null;

    this.fetchData = function(force_reload) {
        if (entries == null || force_reload) {
            entries = HttpConnector.doGet('/collection/'+collection+'/feed/entries/?output=json');
            entries = entries.evalJSON(true);
        }
        if (comments == null || force_reload) {
            comments = HttpConnector.doGet('/collection/'+collection+'/feed/comments/?output=json');
            comments = comments.evalJSON(true);
        }
        if (tags == null || force_reload) {
            tags = HttpConnector.doGet('/collection/'+collection+'/feed/tags/?output=json');
            tags = tags.evalJSON(true);
        }
    }

    this.getComments = function(entry_path) {
        this.fetchData()
        var result = new Array();
        for (var i = 0; i < comments.data.length; i += 1) {
            if (comments.data[i][0].indexOf(entry_path) >= 0) {
                try {
                    result.push(comments.data[i][1].evalJSON(true));
                } catch (e) {
                }
            }
        }
        return result;
    }

    this.getCommentCount = function(entry_path) {
        this.fetchData();
        var count = 0;
        for (var i = 0; i < comments.data.length; i += 1) {
            if (comments.data[i][0].indexOf(entry_path) >= 0) {
                count += 1;
            }
        }
        return count;
    }

    this.getRealName = function(){
        var data = HttpConnector.doGet('/info?output=json');
        var obj = data.evalJSON(true);
        var defaultProfile = obj['default_profile'];
        return HttpConnector.doGet('/collection/'+defaultProfile+'/info/title');
    }

    this.getFeedTitle = function() {
        return HttpConnector.doGet('/collection/'+collection+'/info/title') || "Untitled Blog";
    }

    this.getEntries = function() {
        this.fetchData();
        var keys = entries.data;
        var result = new Array();
        for (var i = 0; i < keys.length; i += 1) {
            if (keys[i][0].match(/.+/)) {
                result.push(keys[i]);
            }
        }
        return result;
    }

    this.getEntry = function(entry_id) {
        var entry = HttpConnector.doGet('/collection/'+collection+'/feed/entries/'+entry_id);
        return entry.evalJSON(true);
    }
    
    this.getEntryPath = function(index) {
        this.fetchData();
        var entries_data = entries.data;
        return (entries_data[index][0].match(/(\w*\/\w*)/))[1];
    }

    this.getMyTags = function(entry_path) {
        var tags_data = tags.data;
        var info = HttpConnector.doGet('/info?output=json');
        info = info.evalJSON(true);
        var defaultProfile = info['default_profile'];
        var fingerprint = HttpConnector.doGet('/collection/'+defaultProfile+'?output=sha1-hex');
        for (var i=0; i<tags_data.length; i++) {
            if (tags_data[i][0] == entry_path+'/0x'+fingerprint) {
                return tags_data[i][1].evalJSON().join(", ");
            }
        }
    }

    this.getNickname = function() {
        var nick = comment_nickname.value;
        if (nick == '') {
            nick = this.getRealName();
        }
        return nick;
    }

    this.removeEmptyIndices = function(tag_array) {
        var ret = new Array();
        for (var i=0; i<tag_array.length; i += 1) {
            if (tag_array[i] != '') {
                ret.push(tag_array[i]);
            }
        }
        return ret;
    }

    this.removeDuplicates = function(tag_array) {
        var ret = new Array();
        var obj = new Object;
        for (var i=0; i<tag_array.length; i += 1) {
            obj[tag_array[i]] = 1;
        }
        ret = new Array();
        for(var key in obj) {
            ret.push(key);
        }
        return ret;
    }

    this.getTags = function(entry_id) {   
        this.fetchData();
        var entry_tags = new Array();
        for (var i = 0; i < tags.data.length; i += 1) {
            if (tags.data[i][0].indexOf(entry_id) >= 0) {
                try {
                    var tag_array = tags.data[i][1].evalJSON(true);
                    tag_array = this.removeEmptyIndices(tag_array);
                    tag_array = this.removeDuplicates(tag_array);
                    if (tag_array.length > 0)
                        entry_tags = entry_tags.concat(tag_array);
                }
                catch (e) {
                    alert(e);
                }
            }
        }
        return entry_tags;
    }

    this.getPopularTags = function(entry_id, limit) {
        if (!limit) limit = 5;
        var tag_array = this.getTags(entry_id);
        var assoc = new Object;
        var uniqtags = 0;
        for (var i=0; i<tag_array.length; i+= 1) {
            if (tag_array[i].length > 30) { // Tag too long
                continue;
            }
            if (assoc[tag_array[i]] == null) {
                assoc[tag_array[i]] = 1;
                uniqtags += 1;
            }
            else {
                assoc[tag_array[i]] += 1;
            }
        }
        var ret = new Array();
        for (var i=0; i<limit && i<uniqtags; i+= 1) {
            var greatest = null;
            for (var key in assoc) {
                if ((assoc[key] > assoc[greatest])||(greatest == null))
                    greatest = key;
            }
            if (greatest != null) {
                ret.push(greatest);
                delete assoc[greatest];
            }
        }
        return ret;
    }

    this.postComment = function(entry_id, nick, tags, msg) {
        var profile = Util.getDefaultProfile();
        if(!profile) return;
        var comment = Object.toJSON({
            published: Util.getUTCDate(),
            author: {
                profile: profile,
                name: nick
            },
            content: msg
        });
        
        tags = tags.replace(/\W+/g, ","); // Convert all white space & special characters to commas..
        tags = Object.toJSON(tags.split(','));
        
        try {
            if (msg != '') {
                var url =  '/collection/' + collection + '/feed/comments/' + entry_id + '/' + Util.getUTCDate();
                HttpConnector.doPost(url, comment);
            }
            var url =  '/collection/' + collection + '/feed/tags/' + entry_id;
            HttpConnector.doPost(url, tags);
            this.fetchData(true);
        } catch (e) {
            alert(e);
        }
    }

    this.postEntry = function(postObject) {  
        var profile = Util.getDefaultProfile();
        if(!profile) return false;
        if(!postObject['id']) {
            postObject['id'] = 'http://hiit.fi/P2P-Fusion/Blog/'+Util.randomHex(30);
            postObject['published'] = update_date;
        }
        if(!postObject['published']) {
            postObject['published'] = Util.getUTCDate();
        }
        var update_date = Util.getUTCDate();
        var entry = {
            id: postObject['id'],
            published: postObject['published'],
            updated: update_date,
            title: postObject['title'],
            author: {
                name: postObject['author'],
                profile: {
                    xmlns: 'http://hiit.fi/P2P-Fusion',
                    $t: profile
                }
            },
            content: postObject['content']
        };
        if (postObject['enclosure_type'] == 'add_new') {
            enclosure_filename = postObject['enclosure_file'].split(/[\/]/);
            enclosure_filename = enclosure_filename[enclosure_filename.length-1];
            entry['link'] = [{
                rel: 'enclosure',
                href: '/collection/'+collection+'/file/'+enclosure_filename
            }];
        } else if (postObject['enclosure_type'] == 'add_existing') {
            entry['link'] = [{
                rel: 'enclosure',
                href: postObject['enclosure_file']
            }];
        }
        
        entry = Object.toJSON(entry);
        if (!postObject['entry_key']) {
            // Generate random hex string with 20 characters (+ leading '0x')
            postObject['entry_key'] = Util.randomHex(20);         
        }
        var url = '/collection/' + collection + '/feed/entries/'+postObject['entry_key'];
        HttpConnector.doPost(url, entry);
        this.fetchData(true);
        return true;
    }

    this.removePost = function(entry_path) {
        var entry_key = entry_path.split('/', 2)[0];
        var url = '/collection/' + collection + '/feed/entries/'+entry_key;
        HttpConnector.doPost(url, '');
    }
}
